home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 001-025 / disk_023 / ver30 / basic.c next >
C/C++ Source or Header  |  1992-05-06  |  8KB  |  372 lines

  1. /*
  2.  * Name:    MicroEMACS
  3.  *        Basic cursor motion commands.
  4.  * Version:    29
  5.  * Last edit:    05-Feb-86
  6.  * By:        rex::conroy
  7.  *        decvax!decwrl!dec-rhea!dec-rex!conroy
  8.  *
  9.  * The routines in this file are the basic
  10.  * command functions for moving the cursor around on
  11.  * the screen, setting mark, and swapping dot with
  12.  * mark. Only moves between lines, which might make the
  13.  * current buffer framing bad, are hard.
  14.  */
  15. #include    "def.h"
  16.  
  17. /*
  18.  * Go to beginning of line.
  19.  */
  20. gotobol(f, n, k)
  21. {
  22.     curwp->w_doto  = 0;
  23.     return (TRUE);
  24. }
  25.  
  26. /*
  27.  * Move cursor backwards. Do the
  28.  * right thing if the count is less than
  29.  * 0. Error if you try to move back from
  30.  * the beginning of the buffer.
  31.  */
  32. backchar(f, n, k)
  33. register int    n;
  34. {
  35.     register LINE    *lp;
  36.  
  37.     if (n < 0)
  38.         return (forwchar(f, -n, KRANDOM));
  39.     while (n--) {
  40.         if (curwp->w_doto == 0) {
  41.             if ((lp=lback(curwp->w_dotp)) == curbp->b_linep)
  42.                 return (FALSE);
  43.             curwp->w_dotp  = lp;
  44.             curwp->w_doto  = llength(lp);
  45.             curwp->w_flag |= WFMOVE;
  46.         } else
  47.             curwp->w_doto--;
  48.     }
  49.     return (TRUE);
  50. }
  51.  
  52. /*
  53.  * Go to end of line.
  54.  */
  55. gotoeol(f, n, k)
  56. {
  57.     curwp->w_doto  = llength(curwp->w_dotp);
  58.     return (TRUE);
  59. }
  60.  
  61. /*
  62.  * Move cursor forwards. Do the
  63.  * right thing if the count is less than
  64.  * 0. Error if you try to move forward
  65.  * from the end of the buffer.
  66.  */
  67. forwchar(f, n, k)
  68. register int    n;
  69. {
  70.     if (n < 0)
  71.         return (backchar(f, -n, KRANDOM));
  72.     while (n--) {
  73.         if (curwp->w_doto == llength(curwp->w_dotp)) {
  74.             if (curwp->w_dotp == curbp->b_linep)
  75.                 return (FALSE);
  76.             curwp->w_dotp  = lforw(curwp->w_dotp);
  77.             curwp->w_doto  = 0;
  78.             curwp->w_flag |= WFMOVE;
  79.         } else
  80.             curwp->w_doto++;
  81.     }
  82.     return (TRUE);
  83. }
  84.  
  85. /*
  86.  * Go to the beginning of the
  87.  * buffer. Setting WFHARD is conservative,
  88.  * but almost always the case.
  89.  */
  90. gotobob(f, n, k)
  91. {
  92.     curwp->w_dotp  = lforw(curbp->b_linep);
  93.     curwp->w_doto  = 0;
  94.     curwp->w_flag |= WFHARD;
  95.     return (TRUE);
  96. }
  97.  
  98. /*
  99.  * Go to the end of the buffer.
  100.  * Setting WFHARD is conservative, but
  101.  * almost always the case.
  102.  */
  103. gotoeob(f, n, k)
  104. {
  105.     curwp->w_dotp  = curbp->b_linep;
  106.     curwp->w_doto  = 0;
  107.     curwp->w_flag |= WFHARD;
  108.     return (TRUE);
  109. }
  110.  
  111. /*
  112.  * Move forward by full lines.
  113.  * If the number of lines to move is less
  114.  * than zero, call the backward line function to
  115.  * actually do it. The last command controls how
  116.  * the goal column is set.
  117.  */
  118. forwline(f, n, k)
  119. {
  120.     register LINE    *dlp;
  121.  
  122.     if (n < 0)
  123.         return (backline(f, -n, KRANDOM));
  124.     if ((lastflag&CFCPCN) == 0)        /* Fix goal.        */
  125.         setgoal();
  126.     thisflag |= CFCPCN;
  127.     dlp = curwp->w_dotp;
  128.     while (n-- && dlp!=curbp->b_linep)
  129.         dlp = lforw(dlp);
  130.     curwp->w_dotp  = dlp;
  131.     curwp->w_doto  = getgoal(dlp);
  132.     curwp->w_flag |= WFMOVE;
  133.     return (TRUE);
  134. }
  135.  
  136. /*
  137.  * This function is like "forwline", but
  138.  * goes backwards. The scheme is exactly the same.
  139.  * Check for arguments that are less than zero and
  140.  * call your alternate. Figure out the new line and
  141.  * call "movedot" to perform the motion.
  142.  */
  143. backline(f, n, k)
  144. {
  145.     register LINE    *dlp;
  146.  
  147.     if (n < 0)
  148.         return (forwline(f, -n, KRANDOM));
  149.     if ((lastflag&CFCPCN) == 0)        /* Fix goal.        */
  150.         setgoal();
  151.     thisflag |= CFCPCN;
  152.     dlp = curwp->w_dotp;
  153.     while (n-- && lback(dlp)!=curbp->b_linep)
  154.         dlp = lback(dlp);
  155.     curwp->w_dotp  = dlp;
  156.     curwp->w_doto  = getgoal(dlp);
  157.     curwp->w_flag |= WFMOVE;
  158.     return (TRUE);
  159. }
  160.  
  161. /*
  162.  * Set the current goal column,
  163.  * which is saved in the external variable "curgoal",
  164.  * to the current cursor column. The column is never off
  165.  * the edge of the screen; it's more like display then
  166.  * show position.
  167.  */
  168. setgoal()
  169. {
  170.     register int    c;
  171.     register int    i;
  172.  
  173.     curgoal = 0;                /* Get the position.    */
  174.     for (i=0; i<curwp->w_doto; ++i) {
  175.         c = lgetc(curwp->w_dotp, i);
  176.         if (c == '\t')
  177.             curgoal |= 0x07;
  178.         else if (ISCTRL(c) != FALSE)
  179.             ++curgoal;
  180.         ++curgoal;
  181.     }
  182.     if (curgoal >= ncol)            /* Chop to tty width.    */
  183.         curgoal = ncol-1;
  184. }
  185.  
  186. /*
  187.  * This routine looks at a line (pointed
  188.  * to by the LINE pointer "dlp") and the current
  189.  * vertical motion goal column (set by the "setgoal"
  190.  * routine above) and returns the best offset to use
  191.  * when a vertical motion is made into the line.
  192.  */
  193. getgoal(dlp)
  194. register LINE    *dlp;
  195. {
  196.     register int    c;
  197.     register int    col;
  198.     register int    newcol;
  199.     register int    dbo;
  200.  
  201.     col = 0;
  202.     dbo = 0;
  203.     while (dbo != llength(dlp)) {
  204.         c = lgetc(dlp, dbo);
  205.         newcol = col;
  206.         if (c == '\t')
  207.             newcol |= 0x07;
  208.         else if (ISCTRL(c) != FALSE)
  209.             ++newcol;
  210.         ++newcol;
  211.         if (newcol > curgoal)
  212.             break;
  213.         col = newcol;
  214.         ++dbo;
  215.     }
  216.     return (dbo);
  217. }
  218.  
  219. /*
  220.  * Scroll forward by a specified number
  221.  * of lines, or by a full page if no argument.
  222.  * The "2" is the window overlap (this is the default
  223.  * value from ITS EMACS). Because the top line in
  224.  * the window is zapped, we have to do a hard
  225.  * update and get it back.
  226.  */
  227. forwpage(f, n, k)
  228. register int    n;
  229. {
  230.     register LINE    *lp;
  231.  
  232.     if (f == FALSE) {
  233.         n = curwp->w_ntrows - 2;    /* Default scroll.    */
  234.         if (n <= 0)            /* Forget the overlap    */
  235.             n = 1;            /* if tiny window.    */
  236.     } else if (n < 0)
  237.         return (backpage(f, -n, KRANDOM));
  238. #if    CVMVAS
  239.     else                    /* Convert from pages    */
  240.         n *= curwp->w_ntrows;        /* to lines.        */
  241. #endif
  242.     lp = curwp->w_linep;
  243.     while (n-- && lp!=curbp->b_linep)
  244.         lp = lforw(lp);
  245.     curwp->w_linep = lp;
  246.     curwp->w_dotp  = lp;
  247.     curwp->w_doto  = 0;
  248.     curwp->w_flag |= WFHARD;
  249.     return (TRUE);
  250. }
  251.  
  252. /*
  253.  * This command is like "forwpage",
  254.  * but it goes backwards. The "2", like above,
  255.  * is the overlap between the two windows. The
  256.  * value is from the ITS EMACS manual. The
  257.  * hard update is done because the top line in
  258.  * the window is zapped.
  259.  */
  260. backpage(f, n, k)
  261. register int    n;
  262. {
  263.     register LINE    *lp;
  264.  
  265.     if (f == FALSE) {
  266.         n = curwp->w_ntrows - 2;    /* Default scroll.    */
  267.         if (n <= 0)            /* Don't blow up if the    */
  268.             n = 1;            /* window is tiny.    */
  269.     } else if (n < 0)
  270.         return (forwpage(f, -n, KRANDOM));
  271. #if    CVMVAS
  272.     else                    /* Convert from pages    */
  273.         n *= curwp->w_ntrows;        /* to lines.        */
  274. #endif
  275.     lp = curwp->w_linep;
  276.     while (n-- && lback(lp)!=curbp->b_linep)
  277.         lp = lback(lp);
  278.     curwp->w_linep = lp;
  279.     curwp->w_dotp  = lp;
  280.     curwp->w_doto  = 0;
  281.     curwp->w_flag |= WFHARD;
  282.     return (TRUE);
  283. }
  284.  
  285. /*
  286.  * Set the mark in the current window
  287.  * to the value of dot. A message is written to
  288.  * the echo line unless we are running in a keyboard
  289.  * macro, when it would be silly.
  290.  */
  291. setmark(f, n, k)
  292. {
  293.     isetmark();
  294.     if (kbdmop == NULL)
  295.         eprintf("[Mark set]");
  296.     return (TRUE);
  297. }
  298.  
  299. /* 
  300.  * So other commands can set the mark easily.  (daveb)
  301.  */
  302. isetmark()
  303. {
  304.     curwp->w_markp = curwp->w_dotp;
  305.     curwp->w_marko = curwp->w_doto;
  306. }
  307.  
  308.  
  309. /*
  310.  * Swap the values of "dot" and "mark" in
  311.  * the current window. This is pretty easy, because
  312.  * all of the hard work gets done by the standard routine
  313.  * that moves the mark about. The only possible
  314.  * error is "no mark".
  315.  */
  316. swapmark(f, n, k)
  317. {
  318.     register LINE    *odotp;
  319.     register int    odoto;
  320.  
  321.     if (curwp->w_markp == NULL) {
  322.         eprintf("No mark in this window");
  323.         return (FALSE);
  324.     }
  325.     odotp = curwp->w_dotp;
  326.     odoto = curwp->w_doto;
  327.     curwp->w_dotp  = curwp->w_markp;
  328.     curwp->w_doto  = curwp->w_marko;
  329.     curwp->w_markp = odotp;
  330.     curwp->w_marko = odoto;
  331.     curwp->w_flag |= WFMOVE;
  332.     return (TRUE);
  333. }
  334.  
  335. /*
  336.  * Go to a specific line, mostly for
  337.  * looking up errors in C programs, which give the
  338.  * error a line number. If an argument is present, then
  339.  * it is the line number, else prompt for a line number
  340.  * to use.
  341.  */
  342. gotoline(f, n, k)
  343. register int    n;
  344. {
  345.     register LINE    *clp;
  346.     register int    s;
  347.     char        buf[32];
  348.  
  349.     if (f == FALSE) {
  350.         if ((s=ereply("Goto line: ", buf, sizeof(buf))) != TRUE)
  351.             return (s);
  352.         n = atoi(buf);
  353.     }
  354.     if (n <= 0) {
  355.         eprintf("Bad line");
  356.         return (FALSE);
  357.     }
  358.     clp = lforw(curbp->b_linep);        /* "clp" is first line    */
  359.     while (n != 1) {
  360.         if (clp == curbp->b_linep) {
  361.             eprintf("Line number too large");
  362.             return (FALSE);
  363.         }
  364.         clp = lforw(clp);
  365.         --n;
  366.     }
  367.     curwp->w_dotp = clp;
  368.     curwp->w_doto = 0;
  369.     curwp->w_flag |= WFMOVE;
  370.     return (TRUE);
  371. }
  372.